home *** CD-ROM | disk | FTP | other *** search
- /*
- GeometrySample.c
-
- This is a simple library illustrating trigrid geometries representing a
- Flat 5x5, Torus, Wavey Torus, Splash, Sphere, Cone, Pipe, Steps, and Spring.
-
- NewLibraryTriGrid returns a trigrid geometry when kGeometryLibraryRange_Simple
- is added to the trigrid number (0 to 8) or a trigrid with shading uv attributes
- when kGeometryLibraryRange_UVGeoAttributes or kGeometryLibraryRange_UVFaceAttributes
- is added to the trigrid number.
-
- Note: The calculation of uv's may be flipping the texture.
-
-
- Robert Dierkes - March 22, 1995
- © 1995 Apple Computer, Inc.
-
- Modification History:
-
- 03/22/95 rdd initial version
- */
-
- #include <Memory.h>
- #include "math.h"
-
- #include "QD3D.h"
- #include "QD3DGeometry.h"
- #include "QD3DMath.h"
- #include "AttributeSet_Lib.h"
-
- #include "GeometrySample.h"
- #include "MathUtilities.h"
-
-
- unsigned long GetLibraryMaxSimpleTriGrid(void)
- {
- return kGeometryLibrary_TriGridMaxSimple;
- }
-
-
-
- /*
- * NewLibraryTriGrid
- *
- * There are two methods below for creating trigrid vertices. If the trigrid is:
- *
- * 1. planar (relatively) then the vvValue (an x-coordinate) increases from vvMin to vvMax.
- * 2. a cross section revolved about the Y axis then the vvValue (an angle) decreases from
- * vvMax to vvMin in a counter-clockwise manner about the axis. This puts the correct
- * side of the trigrid facing outward for texture uvs.
- *
- * In both cases, uuValue decreases from uuMax to uuMin from postive to negative Y.
- *
- * TriGrid vertex index numbering
- *
- * (i)
- * 8 9 10 11
- * 4 5 6 7
- * 0 1 2 3
- *
- *
- * UVs for an upright texture continuous across the trigrid
- *
- * (U,V)
- * (x,y)
- *
- * ^ + 0.0, 1.0 0.33, 1.0 0.66, 1.0 1.0, 1.0
- * | 0.0, 0.5 0.33, 0.5 0.66, 0.5 1.0, 0.5
- * V - 0.0, 0.0 0.33, 0.0 0.66, 0.0 1.0, 0.0
- *
- * U -->
- * - +
- *
- * UVs for an upright repeated texture
- *
- * (U,V)
- * (x,y)
- *
- * ^ + 0,2 1,2 2,2 3,2
- * | 0,1 1,1 2,1 3,1
- * V - 0,0 1,0 2,0 3,0
- *
- * U -->
- * - +
- */
- TQ3GeometryObject NewLibraryTriGrid(unsigned long num)
- {
- TQ3GeometryObject geometryObject = NULL;
- TQ3TriGridData data;
- TQ3Vertex3D *vertices;
- unsigned long i;
- float uuValue, vvValue,
- uuMin, uuMax, uuStep,
- vvMin, vvMax, vvStep,
- radius;
- TQ3Boolean hasUVAttributes;
- TQ3Param2D param2D;
-
- hasUVAttributes = (TQ3Boolean) (mHasUVGeoAttributes(num) || mHasUVFaceAttributes(num));
-
- switch (num)
- {
- case kGeometryLibraryRange_Simple+0: // Flat 5x5
- case kGeometryLibraryRange_UVGeoAttributes+0:
- case kGeometryLibraryRange_UVFaceAttributes+0:
- case kGeometryLibraryRange_Simple+3: // Splash
- case kGeometryLibraryRange_UVGeoAttributes+3:
- case kGeometryLibraryRange_UVFaceAttributes+3:
- case kGeometryLibraryRange_Simple+7: // Steps
- case kGeometryLibraryRange_UVGeoAttributes+7:
- case kGeometryLibraryRange_UVFaceAttributes+7:
- {
- /* Setup min, max and step values trigrid vertex u & v values */
- switch (num)
- {
- /**
- ** Flat 5x5
- **/
- case kGeometryLibraryRange_Simple+0:
- case kGeometryLibraryRange_UVGeoAttributes+0:
- case kGeometryLibraryRange_UVFaceAttributes+0:
-
- /*
- * uuValue is an x-coordinate
- * vvValue is a y-coordinate
- */
- uuMin = -0.5;
- uuMax = 0.5;
- uuStep = 0.25;
-
- vvMin = -0.5;
- vvMax = 0.5;
- vvStep = 0.25;
- break;
-
- /**
- ** Splash
- **/
- case kGeometryLibraryRange_Simple+3:
- case kGeometryLibraryRange_UVGeoAttributes+3:
- case kGeometryLibraryRange_UVFaceAttributes+3:
-
- /*
- * uuValue is an x-coordinate
- * vvValue is a y-coordinate
- */
- uuMin = -3.5;
- uuMax = 3.5;
- vvMin = -3.5;
- vvMax = 3.5;
- if (hasUVAttributes) {
- uuStep = 0.35;
- vvStep = 0.35;
- } else {
- uuStep = 0.25;
- vvStep = 0.25;
- }
- break;
-
- /**
- ** Steps
- **/
- case kGeometryLibraryRange_Simple+7:
- case kGeometryLibraryRange_UVGeoAttributes+7:
- case kGeometryLibraryRange_UVFaceAttributes+7:
-
- /*
- * uuValue is an x-coordinate
- * vvValue is a y-coordinate
- */
- #define kStepScale 0.2
-
- uuMin = -4.5;
- uuMax = 4.5;
- uuStep = 0.5;
-
- vvMin = -4.5;
- vvMax = 4.5;
- vvStep = 0.5;
- break;
-
- default:
- DebugStr("\pWarning: NewLibraryTriGrid ; unknown flat trigrid index");
- return NULL;
- break;
- }
-
-
- /* Setup TQ3TriGridData */
- data.numRows = (unsigned long) ((vvMax - vvMin) / vvStep) + 1;
- data.numColumns = (unsigned long) ((uuMax - uuMin) / uuStep) + 1;
- data.facetAttributeSet = NULL;
- data.triGridAttributeSet= NULL;
-
- data.vertices = (TQ3Vertex3D *) NewPtr (data.numRows * data.numColumns * sizeof(TQ3Vertex3D));
- if (data.vertices == NULL)
- {
- DebugStr("\pError: NewLibraryTriGrid ; Out of memory for triGrid vertices, geometry library number");
- return NULL;
- }
-
- /* Set trigrid vertices and shading UVs, if it hasUVAttributes */
- vertices = data.vertices;
- i = 0;
- for (vvValue = vvMin; vvValue <= vvMax; vvValue += vvStep)
- {
- for (uuValue = uuMin; uuValue <= uuMax; uuValue += uuStep)
- {
- switch (num)
- {
- /* Flat 5x5 */
- case kGeometryLibraryRange_Simple+0:
- case kGeometryLibraryRange_UVGeoAttributes+0:
- case kGeometryLibraryRange_UVFaceAttributes+0:
- vertices[i].point.x = uuValue;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = 0;
- break;
-
- /* Splash */
- case kGeometryLibraryRange_Simple+3:
- case kGeometryLibraryRange_UVGeoAttributes+3:
- case kGeometryLibraryRange_UVFaceAttributes+3:
- vertices[i].point.x = uuValue;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = 1.5 * uMath_Sin_Deg(48.0 * uuValue * vvValue) *
- uMath_Cos_Deg(48.0 * uuValue * vvValue);
- break;
-
- /* Steps */
- case kGeometryLibraryRange_Simple+7:
- case kGeometryLibraryRange_UVGeoAttributes+7:
- case kGeometryLibraryRange_UVFaceAttributes+7:
- vertices[i].point.x = uuValue;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = kStepScale * (((long) uuValue) % ((data.numRows-1)/2)) *
- (((long) vvValue) % ((data.numColumns-1)/2));
- break;
- }
-
- if (hasUVAttributes)
- {
- if (mHasUVGeoAttributes(num))
- {
- param2D.u = (uuValue - uuMin) / (uuMax - uuMin);
- param2D.v = (vvValue - vvMin) / (vvMax - vvMin);
- }
- else /* mHasUVFaceAttributes */
- {
- param2D.u = i % data.numColumns;
- param2D.v = i / data.numColumns;
- }
-
- vertices[i].attributeSet = Q3AttributeSet_New();
- Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeShadingUV, ¶m2D);
- }
- else
- vertices[i].attributeSet = NULL;
-
- i++;
- }
- }
-
- geometryObject = Q3TriGrid_New (&data);
-
- if (hasUVAttributes)
- {
- for (i = 0; i < data.numRows * data.numColumns; i++)
- Q3Object_Dispose(vertices[i].attributeSet);
- }
- DisposePtr ((void *) vertices);
- }
- break;
-
- case kGeometryLibraryRange_Simple+1: // Torus
- case kGeometryLibraryRange_UVGeoAttributes+1:
- case kGeometryLibraryRange_UVFaceAttributes+1:
- case kGeometryLibraryRange_Simple+2: // Wavey Torus
- case kGeometryLibraryRange_UVGeoAttributes+2:
- case kGeometryLibraryRange_UVFaceAttributes+2:
- case kGeometryLibraryRange_Simple+4: // Sphere
- case kGeometryLibraryRange_UVGeoAttributes+4:
- case kGeometryLibraryRange_UVFaceAttributes+4:
- case kGeometryLibraryRange_Simple+5: // Cone
- case kGeometryLibraryRange_UVGeoAttributes+5:
- case kGeometryLibraryRange_UVFaceAttributes+5:
- case kGeometryLibraryRange_Simple+6: // Pipe
- case kGeometryLibraryRange_UVGeoAttributes+6:
- case kGeometryLibraryRange_UVFaceAttributes+6:
- case kGeometryLibraryRange_Simple+8: // Spring
- case kGeometryLibraryRange_UVGeoAttributes+8:
- case kGeometryLibraryRange_UVFaceAttributes+8:
- {
- /* Setup min, max and step values trigrid vertex u & v values */
- switch (num)
- {
- /**
- ** Torus
- **/
- case kGeometryLibraryRange_Simple+1:
- case kGeometryLibraryRange_UVGeoAttributes+1:
- case kGeometryLibraryRange_UVFaceAttributes+1:
- /**
- ** Wavey Torus
- **/
- case kGeometryLibraryRange_Simple+2:
- case kGeometryLibraryRange_UVGeoAttributes+2:
- case kGeometryLibraryRange_UVFaceAttributes+2:
-
- /*
- * uuValue is used to generate each circular cross section about the y axis
- * vvValue is used to revolve the circular cross section about the torus' center
- */
- #define kTorusCrossRadius 0.5
- #define kTorusInnerRadius 1.0
- #define kTorusWaveyAmpRadius 5.0
-
- uuMin = 0.0;
- uuMax = 360.0;
- vvMin = -180.0;
- vvMax = 180.0;
- if (hasUVAttributes) {
- uuStep = 12.0;
- vvStep = 12.0;
- } else {
- uuStep = 10.0;
- vvStep = 10.0;
- }
- break;
-
- /**
- ** Sphere
- **/
- case kGeometryLibraryRange_Simple+4:
- case kGeometryLibraryRange_UVGeoAttributes+4:
- case kGeometryLibraryRange_UVFaceAttributes+4:
-
- /*
- * uuValue is an angle used to revolve the cross section about the y axis
- * vvValue is an angle used to generate each half circular cross section
- */
- uuMin = 0.0;
- uuMax = 360.0;
- vvMin = - 90.0;
- vvMax = 90.0;
- if (hasUVAttributes) {
- uuStep = 12.0;
- vvStep = 12.0;
- } else {
- uuStep = 9.0;
- vvStep = 9.0;
- }
- radius = 1.0;
- break;
-
- /**
- ** Cone
- **/
- case kGeometryLibraryRange_Simple+5:
- case kGeometryLibraryRange_UVGeoAttributes+5:
- case kGeometryLibraryRange_UVFaceAttributes+5:
-
- /*
- * vvValue is the length of the cone side from point to the edge
- * uuValue is an angle used to revolve the cross section about the y axis
- */
- if (hasUVAttributes) {
- uuStep = 24.0;
- vvStep = 0.25;
- } else {
- uuStep = 10.0;
- vvStep = 0.25;
- }
- uuMin = 0.0;
- uuMax = 360.0;
- vvMin = -vvStep;
- vvMax = 2.0;
-
- radius = 0.5;
- break;
-
- /**
- ** Pipe
- **/
- case kGeometryLibraryRange_Simple+6:
- case kGeometryLibraryRange_UVGeoAttributes+6:
- case kGeometryLibraryRange_UVFaceAttributes+6:
-
- /*
- * uuValue is used to revolve the line cross section about the y axis
- * vvValue is used to generate the length of the pipe
- */
- if (hasUVAttributes) {
- uuStep = 20.0;
- vvStep = 0.5;
- } else {
- uuStep = 15.0;
- vvStep = 0.3;
- }
- uuMin = 0.0;
- uuMax = 360.0;
- vvMin = - 1.5;
- vvMax = 1.5;
- #ifdef FINISH_THIS
- vvMin = - 1.5 - vvStep;
- vvMax = 1.5 + vvStep;
- #else /* FINISH_THIS */
- vvMin = - 1.5;
- vvMax = 1.5;
- #endif /* FINISH_THIS */
- radius = 1.0;
- break;
-
- /**
- ** Spring
- **/
- case kGeometryLibraryRange_Simple+8:
- case kGeometryLibraryRange_UVGeoAttributes+8:
- case kGeometryLibraryRange_UVFaceAttributes+8:
-
- /*
- * uuValue is used to revolve the circular cross section about the springs' axis
- * vvValue is used to generate each circular cross section
- */
- #define kSpringCrossRadius 0.25
- #define kSpringInnerRadius 1.0
- #define kSpringSpacing 3.5*kSpringCrossRadius
-
- uuMin = - 90.0;
- uuMax = 810.0;
- vvMin = -180.0;
- vvMax = 180.0;
- if (hasUVAttributes) {
- uuStep = 30.0;
- vvStep = 30.0;
- } else {
- uuStep = 20.0;
- vvStep = 15.0;
- }
- break;
-
- default:
- DebugStr("\pWarning: NewLibraryTriGrid ; unknown revolved trigrid index");
- return NULL;
- break;
- }
-
-
- /* Setup TQ3TriGridData */
- data.numRows = (unsigned long) ((vvMax - vvMin) / vvStep) + 1;
- data.numColumns = (unsigned long) ((uuMax - uuMin) / uuStep) + 1;
- data.facetAttributeSet = NULL;
- data.triGridAttributeSet= NULL;
-
- data.vertices = (TQ3Vertex3D *) NewPtr (data.numRows * data.numColumns * sizeof(TQ3Vertex3D));
- if (data.vertices == NULL)
- {
- DebugStr("\pError: NewLibraryTriGrid ; Out of memory for triGrid vertices.");
- return NULL;
- }
-
- /* Set trigrid vertices and shading UVs, if it hasUVAttributes */
- vertices = data.vertices;
- i = 0;
- for (vvValue = vvMin; vvValue <= vvMax; vvValue += vvStep)
- {
- for (uuValue = uuMax; uuValue >= uuMin; uuValue -= uuStep)
- {
- switch (num)
- {
- /* Torus */
- case kGeometryLibraryRange_Simple+1:
- case kGeometryLibraryRange_UVGeoAttributes+1:
- case kGeometryLibraryRange_UVFaceAttributes+1:
- vertices[i].point.x = (uMath_Cos_Deg(vvValue) * kTorusCrossRadius + kTorusInnerRadius) * uMath_Cos_Deg(uuValue);
- vertices[i].point.y = uMath_Sin_Deg(vvValue) * kTorusCrossRadius;
- vertices[i].point.z = (uMath_Cos_Deg(vvValue) * kTorusCrossRadius + kTorusInnerRadius) * uMath_Sin_Deg(uuValue);
- break;
-
- /* Wavey Torus */
- case kGeometryLibraryRange_Simple+2:
- case kGeometryLibraryRange_UVGeoAttributes+2:
- case kGeometryLibraryRange_UVFaceAttributes+2:
- radius = kTorusCrossRadius / kTorusWaveyAmpRadius * uMath_Sin_Deg(kTorusWaveyAmpRadius * uuValue) + kTorusCrossRadius;
- vertices[i].point.x = (uMath_Cos_Deg(vvValue) * radius + kTorusInnerRadius) * uMath_Cos_Deg(uuValue);
- vertices[i].point.y = uMath_Sin_Deg(vvValue) * radius;
- vertices[i].point.z = (uMath_Cos_Deg(vvValue) * radius + kTorusInnerRadius) * uMath_Sin_Deg(uuValue);
- break;
-
- /* Sphere */
- case kGeometryLibraryRange_Simple+4:
- case kGeometryLibraryRange_UVGeoAttributes+4:
- case kGeometryLibraryRange_UVFaceAttributes+4:
- vertices[i].point.x = uMath_Cos_Deg(vvValue) * uMath_Cos_Deg(uuValue) * radius;
- vertices[i].point.y = uMath_Sin_Deg(vvValue) * radius;
- vertices[i].point.z = uMath_Cos_Deg(vvValue) * uMath_Sin_Deg(uuValue) * radius;
- break;
-
- /* Cone */
- case kGeometryLibraryRange_Simple+5:
- case kGeometryLibraryRange_UVGeoAttributes+5:
- case kGeometryLibraryRange_UVFaceAttributes+5:
- if (vvValue < (vvMin + vvStep))
- {
- vertices[i].point.x = 0.0;
- vertices[i].point.y = vvMin + vvStep;
- vertices[i].point.z = 0.0;
- }
- else
- {
- vertices[i].point.x = (vvMax - vvValue) * uMath_Cos_Deg(uuValue) * radius;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = (vvMax - vvValue) * uMath_Sin_Deg(uuValue) * radius;
- }
- break;
-
- /* Pipe */
- case kGeometryLibraryRange_Simple+6:
- case kGeometryLibraryRange_UVGeoAttributes+6:
- case kGeometryLibraryRange_UVFaceAttributes+6:
- #ifdef FINISH_THIS
- if (vvValue < (vvMin + vvStep))
- {
- vertices[i].point.x = 0.0;
- vertices[i].point.y = vvMin + vvStep;
- vertices[i].point.z = 0.0;
- }
- else
- if (vvValue > (vvMax - vvStep))
- {
- vertices[i].point.x = 0.0;
- vertices[i].point.y = vvMax - vvStep;
- vertices[i].point.z = 0.0;
- }
- else
- {
- vertices[i].point.x = uMath_Cos_Deg(uuValue) * radius;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = uMath_Sin_Deg(uuValue) * radius;
- }
- #else /* FINISH_THIS */
- vertices[i].point.x = radius * uMath_Cos_Deg(uuValue);
- vertices[i].point.y = vvValue;
- vertices[i].point.z = radius * uMath_Sin_Deg(uuValue);
- #endif /* FINISH_THIS */
- break;
-
- /* Spring */
- case kGeometryLibraryRange_Simple+8:
- case kGeometryLibraryRange_UVGeoAttributes+8:
- case kGeometryLibraryRange_UVFaceAttributes+8:
- vertices[i].point.x = (uMath_Cos_Deg(vvValue) * kSpringCrossRadius + kSpringInnerRadius) * uMath_Cos_Deg(uuValue);
- vertices[i].point.y = uMath_Sin_Deg(vvValue) * kSpringCrossRadius + kSpringSpacing * uuValue/360.0;
- vertices[i].point.z = (uMath_Cos_Deg(vvValue) * kSpringCrossRadius + kSpringInnerRadius) * uMath_Sin_Deg(uuValue);
- break;
- }
-
- if (hasUVAttributes)
- {
- if (mHasUVGeoAttributes(num))
- {
- param2D.u = 1.0 - ((uuValue - uuMin) / (uuMax - uuMin));
- param2D.v = (vvValue - vvMin) / (vvMax - vvMin);
- }
- else /* mHasUVFaceAttributes */
- {
- param2D.u = i % data.numColumns;
- param2D.v = i / data.numColumns;
- }
-
- vertices[i].attributeSet = Q3AttributeSet_New();
- Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeShadingUV, ¶m2D);
- }
- else
- vertices[i].attributeSet = NULL;
-
- i++;
- }
- }
-
- geometryObject = Q3TriGrid_New (&data);
-
- if (hasUVAttributes)
- {
- for (i = 0; i < data.numRows * data.numColumns; i++)
- Q3Object_Dispose(vertices[i].attributeSet);
- }
- DisposePtr ((void *) vertices);
- }
- break;
-
- default:
- DebugStr("\pWarning: NewLibraryTriGrid ; index unimplemented ");
- break;
- }
- return geometryObject;
- }
-